#include "Mystdio.h"
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>

#define FILE_MODE 0666

_FILE* _fopen(const char* filename,const char* mode){
    assert(filename);
    assert(mode);
    int mod = 0;
    int fd = -1;
    if(*mode == 'w'){
        mod = (O_TRUNC|O_CREAT|O_WRONLY);
        fd = open(filename,mod,FILE_MODE);
    }
    else if(*mode == 'a'){
        mod = (O_APPEND|O_CREAT|O_WRONLY);
        fd = open(filename,mod,FILE_MODE);
    }
    else if(*mode == 'r'){
        mod = O_RDONLY;
        fd = open(filename,mod);
    }
    else return NULL;
    if(fd == -1) return NULL;
    _FILE* fp = (_FILE*)malloc(sizeof(_FILE));
    if(fp == NULL) return NULL;
    fp->fileno = fd;

    fp->out_pos = 0;
    if(fd == 1 || fd == 2) fp->flag = FLUSH_LINE;
    else{
        fp->flag = FLUSH_ALL;
    }
    return fp;

}

int _fwrite(const char* s,int len,_FILE* fp){
    memcpy(&fp->outbuffer[fp->out_pos],s,len);//不做异常处理，也不考虑空间用满问题
    fp->out_pos += len;
    
    if(fp->flag & FLUSH_NOW){
        write(fp->fileno,s,len);
        fp->out_pos = 0;
    }
    else if(fp->flag & FLUSH_LINE){
        if(fp->outbuffer[fp->out_pos - 1] == '\n'){
            write(fp->fileno,fp->outbuffer,fp->out_pos);
            fp->out_pos = 0;
        }
    }
    else if(fp->flag & FLUSH_ALL){
        if(fp->out_pos == SIZE){ 
            write(fp->fileno,fp->outbuffer,fp->out_pos);
            fp->out_pos = 0;
        }
    }

    return len;    
}

void _fflush(_FILE* fp){
    if(fp->out_pos){
        write(fp->fileno,fp->outbuffer,fp->out_pos);
    }
}

void _fclose(_FILE* fp){
    if(fp == NULL) return;
    _fflush(fp);
    close(fp->fileno);
    free(fp);
}
